<!-- Notification.vue -->
<template>
  <div
      :class="['notification', positionClass]"
      @click="handleClick"
  >
    <div class="header">
      <h3>{{ title }}</h3>
      <span class="close-btn" @click.stop="close">×</span>
    </div>
    <div class="content">
      <component :is="messageContent"/>
    </div>
  </div>
</template>

<script setup>
import { computed, ref, onMounted } from 'vue'

const props = defineProps({
  title: { type: String, default: '' },
  message: { type: [String, Object, Function], default: '' },
  duration: { type: Number, default: 5000 },
  position: {
    type: String,
    default: 'topRight',
    validator: (value) => ['topRight', 'topLeft', 'bottomRight', 'bottomLeft'].includes(value)
  },
  closeEndFn: { type: Function },
  clickEndFn: { type: Function }
})

const positionClass = computed(() => `notification-${props.position}`)
const messageContent = computed(() => {
  if (typeof props.message === 'function') return props.message()
  return props.message
})

const timer = ref(null)

onMounted(() => {
  if (props.duration > 0) {
    timer.value = setTimeout(close, props.duration)
  }
})

const close = () => {
  clearTimeout(timer.value)
  if (props.closeEndFn) props.closeEndFn()
}

const handleClick = () => {
  if (props.clickEndFn) props.clickEndFn()
}
</script>

<style scoped>
.notification {
  position: fixed;
  width: 300px;
  padding: 15px;
  background: white;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
  border-radius: 4px;
  transition: all 0.3s;
}

.notification-topRight {
  top: 20px;
  right: 20px;
}

.notification-topLeft {
  top: 20px;
  left: 20px;
}

.notification-bottomRight {
  bottom: 20px;
  right: 20px;
}

.notification-bottomLeft {
  bottom: 20px;
  left: 20px;
}

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}

.close-btn {
  cursor: pointer;
  font-size: 20px;
  padding: 0 5px;
}

.content {
  word-break: break-word;
}

.notification-enter-active,
.notification-leave-active {
  transition: all 0.3s ease;
}

.notification-enter-from,
.notification-leave-to {
  opacity: 0;
  transform: translateX(100%);
}
</style>